// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.core.stash;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import se.krka.kahlua.j2se.KahluaTableImpl;
import se.krka.kahlua.vm.KahluaTable;
import se.krka.kahlua.vm.KahluaTableIterator;
import zombie.Lua.LuaManager;
import zombie.core.Rand;
import zombie.debug.DebugLog;
import zombie.inventory.InventoryItem;
import zombie.inventory.InventoryItemFactory;
import zombie.inventory.ItemContainer;
import zombie.inventory.ItemPickerJava;
import zombie.inventory.types.HandWeapon;
import zombie.inventory.types.InventoryContainer;
import zombie.inventory.types.MapItem;
import zombie.iso.BuildingDef;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.IsoWorld;
import zombie.iso.RoomDef;
import zombie.iso.objects.IsoDeadBody;
import zombie.iso.objects.IsoDoor;
import zombie.iso.objects.IsoThumpable;
import zombie.iso.objects.IsoTrap;
import zombie.iso.objects.IsoWindow;
import zombie.iso.objects.interfaces.BarricadeAble;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.ui.UIFont;
import zombie.util.Type;
import zombie.worldMap.symbols.WorldMapBaseSymbol;

public final class StashSystem {
    public static ArrayList<Stash> allStashes;
    public static ArrayList<StashBuilding> possibleStashes;
    public static ArrayList<StashBuilding> buildingsToDo;
    private static final ArrayList<String> possibleTrap = new ArrayList();
    private static ArrayList<String> alreadyReadMap = new ArrayList();

    public static void init() {
        if (possibleStashes == null) {
            initAllStashes();
            buildingsToDo = new ArrayList();
            possibleTrap.add("Base.FlameTrapSensorV1");
            possibleTrap.add("Base.SmokeBombSensorV1");
            possibleTrap.add("Base.NoiseTrapSensorV1");
            possibleTrap.add("Base.NoiseTrapSensorV2");
            possibleTrap.add("Base.AerosolbombSensorV1");
        }
    }

    public static void initAllStashes() {
        allStashes = new ArrayList();
        possibleStashes = new ArrayList();
        KahluaTable kahluaTable = (KahluaTable)LuaManager.env.rawget("StashDescriptions");
        KahluaTableIterator kahluaTableIterator = kahluaTable.iterator();

        while (kahluaTableIterator.advance()) {
            KahluaTableImpl kahluaTableImpl = (KahluaTableImpl)kahluaTableIterator.getValue();
            Stash stash = new Stash(kahluaTableImpl.rawgetStr("name"));
            stash.load(kahluaTableImpl);
            allStashes.add(stash);
        }
    }

    public static void checkStashItem(InventoryItem item) {
        if (!GameClient.bClient && !possibleStashes.isEmpty()) {
            int int0 = 60;
            if (item.getStashChance() > 0) {
                int0 = item.getStashChance();
            }

            switch (zombie.SandboxOptions.instance.AnnotatedMapChance.getValue()) {
                case 1:
                    return;
                case 2:
                    int0 += 15;
                    break;
                case 3:
                    int0 += 10;
                case 4:
                default:
                    break;
                case 5:
                    int0 -= 10;
                    break;
                case 6:
                    int0 -= 20;
            }

            if (Rand.Next(100) <= 100 - int0) {
                ArrayList arrayList = new ArrayList();

                for (int int1 = 0; int1 < allStashes.size(); int1++) {
                    Stash stash0 = (Stash)allStashes.get(int1);
                    if (stash0.item.equals(item.getFullType()) && checkSpecificSpawnProperties(stash0, item)) {
                        boolean _boolean = false;

                        for (int int2 = 0; int2 < possibleStashes.size(); int2++) {
                            StashBuilding stashBuilding = (StashBuilding)possibleStashes.get(int2);
                            if (stashBuilding.stashName.equals(stash0.name)) {
                                _boolean = true;
                                break;
                            }
                        }

                        if (_boolean) {
                            arrayList.add(stash0);
                        }
                    }
                }

                if (!arrayList.isEmpty()) {
                    Stash stash1 = (Stash)arrayList.get(Rand.Next(0, arrayList.size()));
                    doStashItem(stash1, item);
                }
            }
        }
    }

    public static void doStashItem(Stash stash, InventoryItem item) {
        if (stash.customName != null) {
            item.setName(stash.customName);
        }

        if ("Map".equals(stash.type)) {
            MapItem mapItem = Type.tryCastTo(item, MapItem.class);
            if (mapItem == null) {
                throw new IllegalArgumentException(item + " is not a MapItem");
            }

            if (stash.annotations != null) {
                for (int _int = 0; _int < stash.annotations.size(); _int++) {
                    StashAnnotation stashAnnotation = (StashAnnotation)stash.annotations.get(_int);
                    if (stashAnnotation.symbol != null) {
                        mapItem.getSymbols()
                            .addTexture(
                                stashAnnotation.symbol,
                                stashAnnotation.x,
                                stashAnnotation.y,
                                0.5F,
                                0.5F,
                                WorldMapBaseSymbol.DEFAULT_SCALE,
                                stashAnnotation.r,
                                stashAnnotation.g,
                                stashAnnotation.b,
                                1.0F
                            );
                    } else if (stashAnnotation.text != null) {
                        mapItem.getSymbols()
                            .addUntranslatedText(
                                stashAnnotation.text,
                                UIFont.Handwritten,
                                stashAnnotation.x,
                                stashAnnotation.y,
                                stashAnnotation.r,
                                stashAnnotation.g,
                                stashAnnotation.b,
                                1.0F
                            );
                    }
                }
            }

            removeFromPossibleStash(stash);
            item.setStashMap(stash.name);
        }
    }

    public static void prepareBuildingStash(String stashName) {
        if (stashName != null) {
            Stash stash = getStash(stashName);
            if (stash != null && !alreadyReadMap.contains(stashName)) {
                alreadyReadMap.add(stashName);
                buildingsToDo.add(new StashBuilding(stash.name, stash.buildingX, stash.buildingY));
                RoomDef roomDef = IsoWorld.instance.getMetaGrid().getRoomAt(stash.buildingX, stash.buildingY, 0);
                if (roomDef != null && roomDef.getBuilding() != null && roomDef.getBuilding().isFullyStreamedIn()) {
                    doBuildingStash(roomDef.getBuilding());
                }
            }
        }
    }

    private static boolean checkSpecificSpawnProperties(Stash stash, InventoryItem inventoryItem) {
        return !stash.spawnOnlyOnZed || inventoryItem.getContainer() != null && inventoryItem.getContainer().getParent() instanceof IsoDeadBody
            ? (stash.minDayToSpawn <= -1 || zombie.GameTime.instance.getDaysSurvived() >= stash.minDayToSpawn)
                && (stash.maxDayToSpawn <= -1 || zombie.GameTime.instance.getDaysSurvived() <= stash.maxDayToSpawn)
            : false;
    }

    private static void removeFromPossibleStash(Stash stash) {
        for (int _int = 0; _int < possibleStashes.size(); _int++) {
            StashBuilding stashBuilding = (StashBuilding)possibleStashes.get(_int);
            if (stashBuilding.buildingX == stash.buildingX && stashBuilding.buildingY == stash.buildingY) {
                possibleStashes.remove(_int);
                _int--;
            }
        }
    }

    public static void doBuildingStash(BuildingDef def) {
        if (buildingsToDo == null) {
            init();
        }

        for (int int0 = 0; int0 < buildingsToDo.size(); int0++) {
            StashBuilding stashBuilding = (StashBuilding)buildingsToDo.get(int0);
            if (stashBuilding.buildingX > def.x && stashBuilding.buildingX < def.x2 && stashBuilding.buildingY > def.y && stashBuilding.buildingY < def.y2) {
                if (def.hasBeenVisited) {
                    buildingsToDo.remove(int0);
                    int0--;
                } else {
                    Stash stash = getStash(stashBuilding.stashName);
                    if (stash != null) {
                        ItemPickerJava.ItemPickerRoom itemPickerRoom0 = ItemPickerJava.rooms.get(stash.spawnTable);
                        if (itemPickerRoom0 != null) {
                            def.setAllExplored(true);
                            doSpecificBuildingProperties(stash, def);

                            for (int int1 = def.x - 1; int1 < def.x2 + 1; int1++) {
                                for (int int2 = def.y - 1; int2 < def.y2 + 1; int2++) {
                                    for (int int3 = 0; int3 < 8; int3++) {
                                        IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare(int1, int2, int3);
                                        if (isoGridSquare != null) {
                                            for (int int4 = 0; int4 < isoGridSquare.getObjects().size(); int4++) {
                                                IsoObject isoObject = isoGridSquare.getObjects().get(int4);
                                                if (isoObject.getContainer() != null
                                                    && isoGridSquare.getRoom() != null
                                                    && isoGridSquare.getRoom().getBuilding().getDef() == def
                                                    && isoGridSquare.getRoom().getName() != null
                                                    && itemPickerRoom0.Containers.containsKey(isoObject.getContainer().getType())) {
                                                    ItemPickerJava.ItemPickerRoom itemPickerRoom1 = ItemPickerJava.rooms.get(isoGridSquare.getRoom().getName());
                                                    boolean _boolean = false;
                                                    if (itemPickerRoom1 == null || !itemPickerRoom1.Containers.containsKey(isoObject.getContainer().getType())) {
                                                        isoObject.getContainer().clear();
                                                        _boolean = true;
                                                    }

                                                    ItemPickerJava.fillContainerType(itemPickerRoom0, isoObject.getContainer(), "", null);
                                                    ItemPickerJava.updateOverlaySprite(isoObject);
                                                    if (_boolean) {
                                                        isoObject.getContainer().setExplored(true);
                                                    }
                                                }

                                                BarricadeAble barricadeAble = Type.tryCastTo(isoObject, BarricadeAble.class);
                                                if (stash.barricades > -1
                                                    && barricadeAble != null
                                                    && barricadeAble.isBarricadeAllowed()
                                                    && Rand.Next(100) < stash.barricades) {
                                                    if (isoObject instanceof IsoDoor) {
                                                        ((IsoDoor)isoObject).addRandomBarricades();
                                                    } else if (isoObject instanceof IsoWindow) {
                                                        ((IsoWindow)isoObject).addRandomBarricades();
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            buildingsToDo.remove(int0);
                            int0--;
                        }
                    }
                }
            }
        }
    }

    private static void doSpecificBuildingProperties(Stash stash, BuildingDef buildingDef) {
        if (stash.containers != null) {
            ArrayList arrayList0 = new ArrayList();

            for (int int0 = 0; int0 < stash.containers.size(); int0++) {
                StashContainer stashContainer = (StashContainer)stash.containers.get(int0);
                IsoGridSquare isoGridSquare0 = null;
                if (!"all".equals(stashContainer.room)) {
                    for (int int1 = 0; int1 < buildingDef.rooms.size(); int1++) {
                        RoomDef roomDef0 = (RoomDef)buildingDef.rooms.get(int1);
                        if (stashContainer.room.equals(roomDef0.name)) {
                            arrayList0.add(roomDef0);
                        }
                    }
                } else if (stashContainer.contX > -1 && stashContainer.contY > -1 && stashContainer.contZ > -1) {
                    isoGridSquare0 = IsoWorld.instance.getCell().getGridSquare(stashContainer.contX, stashContainer.contY, stashContainer.contZ);
                } else {
                    isoGridSquare0 = buildingDef.getFreeSquareInRoom();
                }

                if (!arrayList0.isEmpty()) {
                    RoomDef roomDef1 = (RoomDef)arrayList0.get(Rand.Next(0, arrayList0.size()));
                    isoGridSquare0 = roomDef1.getFreeSquare();
                }

                if (isoGridSquare0 != null) {
                    if (stashContainer.containerItem != null && !stashContainer.containerItem.isEmpty()) {
                        ItemPickerJava.ItemPickerRoom itemPickerRoom = ItemPickerJava.rooms.get(stash.spawnTable);
                        if (itemPickerRoom == null) {
                            DebugLog.log("Container distribution " + stash.spawnTable + " not found");
                            return;
                        }

                        InventoryItem inventoryItem = InventoryItemFactory.CreateItem(stashContainer.containerItem);
                        if (inventoryItem == null) {
                            DebugLog.General.error("Item " + stashContainer.containerItem + " Doesn't exist.");
                            return;
                        }

                        ItemPickerJava.ItemPickerContainer itemPickerContainer = itemPickerRoom.Containers.get(inventoryItem.getType());
                        ItemPickerJava.rollContainerItem((InventoryContainer)inventoryItem, null, itemPickerContainer);
                        isoGridSquare0.AddWorldInventoryItem(inventoryItem, 0.0F, 0.0F, 0.0F);
                    } else {
                        IsoThumpable isoThumpable = new IsoThumpable(isoGridSquare0.getCell(), isoGridSquare0, stashContainer.containerSprite, false, null);
                        isoThumpable.setIsThumpable(false);
                        isoThumpable.container = new ItemContainer(stashContainer.containerType, isoGridSquare0, isoThumpable);
                        isoGridSquare0.AddSpecialObject(isoThumpable);
                        isoGridSquare0.RecalcAllWithNeighbours(true);
                    }
                } else {
                    DebugLog.log("No free room was found to spawn special container for stash " + stash.name);
                }
            }
        }

        if (stash.minTrapToSpawn > -1) {
            for (int int2 = stash.minTrapToSpawn; int2 < stash.maxTrapToSpawn; int2++) {
                IsoGridSquare isoGridSquare1 = buildingDef.getFreeSquareInRoom();
                if (isoGridSquare1 != null) {
                    HandWeapon handWeapon = (HandWeapon)InventoryItemFactory.CreateItem((String)possibleTrap.get(Rand.Next(0, possibleTrap.size())));
                    if (GameServer.bServer) {
                        GameServer.AddExplosiveTrap(handWeapon, isoGridSquare1, handWeapon.getSensorRange() > 0);
                    } else {
                        IsoTrap isoTrap = new IsoTrap(handWeapon, isoGridSquare1.getCell(), isoGridSquare1);
                        isoGridSquare1.AddTileObject(isoTrap);
                    }
                }
            }
        }

        if (stash.zombies > -1) {
            for (int int3 = 0; int3 < buildingDef.rooms.size(); int3++) {
                RoomDef roomDef2 = (RoomDef)buildingDef.rooms.get(int3);
                if (IsoWorld.getZombiesEnabled()) {
                    byte _byte = 1;
                    int int4 = 0;

                    for (int int5 = 0; int5 < roomDef2.area; int5++) {
                        if (Rand.Next(100) < stash.zombies) {
                            int4++;
                        }
                    }

                    if (zombie.SandboxOptions.instance.Zombies.getValue() == 1) {
                        int4 += 4;
                    } else if (zombie.SandboxOptions.instance.Zombies.getValue() == 2) {
                        int4 += 3;
                    } else if (zombie.SandboxOptions.instance.Zombies.getValue() == 3) {
                        int4 += 2;
                    } else if (zombie.SandboxOptions.instance.Zombies.getValue() == 5) {
                        int4 -= 4;
                    }

                    if (int4 > roomDef2.area / 2) {
                        int4 = roomDef2.area / 2;
                    }

                    if (int4 < _byte) {
                        int4 = _byte;
                    }

                    ArrayList arrayList1 = zombie.VirtualZombieManager.instance.addZombiesToMap(int4, roomDef2, false);
                    zombie.ZombieSpawnRecorder.instance.record(arrayList1, "StashSystem");
                }
            }
        }
    }

    public static Stash getStash(String stashName) {
        for (int _int = 0; _int < allStashes.size(); _int++) {
            Stash stash = (Stash)allStashes.get(_int);
            if (stash.name.equals(stashName)) {
                return stash;
            }
        }

        return null;
    }

    public static void visitedBuilding(BuildingDef def) {
        if (!GameClient.bClient) {
            for (int _int = 0; _int < possibleStashes.size(); _int++) {
                StashBuilding stashBuilding = (StashBuilding)possibleStashes.get(_int);
                if (stashBuilding.buildingX > def.x && stashBuilding.buildingX < def.x2 && stashBuilding.buildingY > def.y && stashBuilding.buildingY < def.y2) {
                    possibleStashes.remove(_int);
                    _int--;
                }
            }
        }
    }

    public static void load(ByteBuffer input, int WorldVersion) {
        init();
        alreadyReadMap = new ArrayList();
        possibleStashes = new ArrayList();
        buildingsToDo = new ArrayList();
        int int0 = input.getInt();

        for (int int1 = 0; int1 < int0; int1++) {
            possibleStashes.add(new StashBuilding(zombie.GameWindow.ReadString(input), input.getInt(), input.getInt()));
        }

        int int2 = input.getInt();

        for (int int3 = 0; int3 < int2; int3++) {
            buildingsToDo.add(new StashBuilding(zombie.GameWindow.ReadString(input), input.getInt(), input.getInt()));
        }

        if (WorldVersion >= 109) {
            int int4 = input.getInt();

            for (int int5 = 0; int5 < int4; int5++) {
                alreadyReadMap.add(zombie.GameWindow.ReadString(input));
            }
        }
    }

    public static void save(ByteBuffer output) {
        if (allStashes != null) {
            output.putInt(possibleStashes.size());

            for (int int0 = 0; int0 < possibleStashes.size(); int0++) {
                StashBuilding stashBuilding0 = (StashBuilding)possibleStashes.get(int0);
                zombie.GameWindow.WriteString(output, stashBuilding0.stashName);
                output.putInt(stashBuilding0.buildingX);
                output.putInt(stashBuilding0.buildingY);
            }

            output.putInt(buildingsToDo.size());

            for (int int1 = 0; int1 < buildingsToDo.size(); int1++) {
                StashBuilding stashBuilding1 = (StashBuilding)buildingsToDo.get(int1);
                zombie.GameWindow.WriteString(output, stashBuilding1.stashName);
                output.putInt(stashBuilding1.buildingX);
                output.putInt(stashBuilding1.buildingY);
            }

            output.putInt(alreadyReadMap.size());

            for (int int2 = 0; int2 < alreadyReadMap.size(); int2++) {
                zombie.GameWindow.WriteString(output, (String)alreadyReadMap.get(int2));
            }
        }
    }

    public static ArrayList<StashBuilding> getPossibleStashes() {
        return possibleStashes;
    }

    public static void reinit() {
        possibleStashes = null;
        alreadyReadMap = new ArrayList();
        init();
    }

    public static void Reset() {
        allStashes = null;
        possibleStashes = null;
        buildingsToDo = null;
        possibleTrap.clear();
        alreadyReadMap.clear();
    }
}
